package com.bestcem.xm.label.grpc.service;

import cn.hutool.core.collection.CollectionUtil;
import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.label.grpc.service.param.label.*;
import com.bestcem.xm.label.grpc.v1.common.BaseMessage;
import com.bestcem.xm.label.grpc.v1.common.CreateResponse;
import com.bestcem.xm.label.grpc.v1.common.DeleteResponse;
import com.bestcem.xm.label.grpc.v1.common.UpdateResponse;
import com.bestcem.xm.label.grpc.v1.services.*;
import com.bestcem.xm.label.service.LabelService;
import com.bestcem.xm.label.service.LabelValueService;
import com.bestcem.xm.label.service.dto.label.LabelDTO;
import com.bestcem.xm.label.service.dto.label.LabelInfoDTO;
import com.bestcem.xm.label.service.dto.label.LabelValueDTO;
import com.google.protobuf.ProtocolStringList;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 标签 相关rpc服务
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/5/21
 */
@Slf4j
@GrpcService
public class LabelGrpcService extends LabelServiceGrpc.LabelServiceImplBase {

    @Resource
    private LabelService labelService;

    @Resource
    private LabelValueService labelValueService;

    /**
     * 获取所有标签列表
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void listLabels(ListLabelsRequest request, StreamObserver<ListLabelsResponse> responseObserver) {
        ListLabelsResponse.Builder builder = ListLabelsResponse.newBuilder();
        // 构建参数
        ListLabelsParam param = requestToListLabelsParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 获取所有的标签信息
        ServiceResult<List<LabelInfoDTO>> serviceResult = labelService.listLabels(param);

        if (serviceResult.isSuccess()) {
            List<LabelInfoDTO> data = serviceResult.getData();
            List<LabelInfo> labelInfos = new ArrayList<>(data.size());
            if (!CollectionUtil.isEmpty(data)) {
                data.forEach(labelInfoDTO -> {
                    LabelInfo info = labelInfoDtoToLabelInfo(labelInfoDTO);
                    labelInfos.add(info);
                });
            }
            builder.addAllLabelInfo(labelInfos);
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 根据标签id列表 获取标签的相关数据
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void getLabelInfo(GetLabelInfoRequest request, StreamObserver<GetLabelInfoResponse> responseObserver) {
        GetLabelInfoResponse.Builder builder = GetLabelInfoResponse.newBuilder();
        // 构建参数
        GetLabelInfoParam param = requestToGetLabelInfoParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 获取标签的详细信息
        ServiceResult<List<LabelDTO>> serviceResult = labelService.getLabelInfo(param.getIds());
        if (serviceResult.isSuccess()) {
            List<LabelDTO> labelDTO = serviceResult.getData();
            builder.addAllLabel(labelDtoListToInfo(labelDTO, true));
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 更新标签值的顺序
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void batchUpdateLabelValues(BatchUpdateLabelValuesRequest request,
                                       StreamObserver<BatchUpdateLabelValuesResponse> responseObserver) {
        BatchUpdateLabelValuesResponse.Builder builder = BatchUpdateLabelValuesResponse.newBuilder();
        // 构建请求参数
        BatchUpdateLabelValuesParm param = requestToBatchUpdateLabelValuesParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 批量更新标签值序号
        ServiceResult<Boolean> serviceResult = labelValueService.batchUpdateLabelValues(param);

        if (serviceResult.isSuccess()) {
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 创建标签
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void createLabel(CreateLabelRequest request, StreamObserver<CreateResponse> responseObserver) {
        CreateResponse.Builder builder = CreateResponse.newBuilder();
        // 构建参数
        CreateLabelParam createLabelParam = requestToCreateLabelParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(createLabelParam);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 标签新增
        ServiceResult<String> serviceResult = labelService.createLabel(createLabelParam);

        if (serviceResult.isSuccess()) {
            builder.setId(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 更新标签
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void updateLabel(UpdateLabelRequest request, StreamObserver<UpdateResponse> responseObserver) {
        UpdateResponse.Builder builder = UpdateResponse.newBuilder();
        // 构建更细标签的参数
        UpdateLabelParam param = requestToUpdateTagParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 更新标签
        ServiceResult<String> serviceResult = labelService.updateLabel(param);

        if (serviceResult.isSuccess()) {
            builder.setId(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 删除标签
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void deleteLabel(DeleteLabelRequest request, StreamObserver<DeleteResponse> responseObserver) {
        DeleteResponse.Builder builder = DeleteResponse.newBuilder();
        // 构建参数
        DeleteLabelParam param = requestToDeleteLabelParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 标签删除
        ServiceResult<String> serviceResult = labelService.deleteLabel(param);

        if (serviceResult.isSuccess()) {
            builder.setId(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 检查标签值名称是否重复
     * 是否与当前标签里的任一标签值是否重名
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void checkLabelValueName(CheckLabelValueNameRequest request,
                                    StreamObserver<CheckLabelValueNameResponse> responseObserver) {
        CheckLabelValueNameResponse.Builder builder = CheckLabelValueNameResponse.newBuilder();
        // 构建参数
        CheckLabelValueNameParam param = requestToCheckTagValueNameParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 检查标签值名称是否重复
        ServiceResult<Boolean> serviceResult = labelValueService.checkLabelValueName(param);

        if (serviceResult.isSuccess()) {
            builder.setRepeat(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据标签值id获取标签值信息
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void listLabelValues(ListLabelValuesRequest request,
                                StreamObserver<ListLabelValuesResponse> responseObserver) {
        ListLabelValuesResponse.Builder builder = ListLabelValuesResponse.newBuilder();
        // 构建参数
        ListLabelValuesParam param = requestToListLabelValuesParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 获取标签值信息
        ServiceResult<List<LabelValueDTO>> serviceResult = labelValueService.listLabelValues(param);

        if (serviceResult.isSuccess()) {
            List<LabelValue> labelValues = new ArrayList<>();
            List<LabelValueDTO> labelValueDTOS = serviceResult.getData();
            if (CollectionUtil.isNotEmpty(labelValueDTOS)) {
                labelValueDTOS.forEach(labelValueDTO -> {
                    LabelValue labelValue = labelValueDtoToLabelValue(labelValueDTO);
                    labelValues.add(labelValue);
                });
            }
            builder.addAllLabelValue(labelValues);
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 检查标签值名称是否重复
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void checkLabelName(CheckLabelNameRequest request,
                               StreamObserver<CheckLabelNameResponse> responseObserver) {

        CheckLabelNameResponse.Builder builder = CheckLabelNameResponse.newBuilder();
        // 构建参数
        CheckLabelNameParam param = requestToCheckLabelNameParam(request);

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 检查标签名称是否重复
        ServiceResult<Boolean> serviceResult = labelService.checkLabelName(param);

        if (serviceResult.isSuccess()) {
            builder.setValid(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listGroupLabels(ListGroupLabelsRequest request, StreamObserver<ListGroupLabelsResponse> responseObserver) {
        ListGroupLabelsResponse.Builder builder = ListGroupLabelsResponse.newBuilder();
        ListGroupLabelsParam param = requestToListGroupLabelsParam(request);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 获取标签的详细信息
        ServiceResult<List<LabelDTO>> serviceResult = labelService.listGroupLabels(param);
        if (serviceResult.isSuccess()) {
            List<LabelDTO> labelDTO = serviceResult.getData();
            builder.addAllLabels(labelDtoListToInfo(labelDTO, true));
            builder.setStatus(RpcStatusResult.success());
        } else {
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    // ========================== private model convert ==========================

    /**
     * request to ListGroupLabelsParam
     *
     * @param request
     * @return
     */
    private ListGroupLabelsParam requestToListGroupLabelsParam(ListGroupLabelsRequest request) {
        ListGroupLabelsParam param = new ListGroupLabelsParam();
        param.setLabelGroupIds(request.getGIdsList());
        param.setOrgId(request.getOrgId());
        return param;
    }

    /**
     * 检查标签值名称是否重复 整合 request 请求参数 便于参数校验
     *
     * @param request
     * @return
     */
    private CheckLabelNameParam requestToCheckLabelNameParam(CheckLabelNameRequest request) {
        CheckLabelNameParam param = new CheckLabelNameParam();
        // 联系人类型
        param.setAttribute(request.getMemberTypeValue());
        // 标签名称
        param.setName(request.getName());
        // 组织id
        param.setOrgId(request.getOrgId());
        return param;
    }


    /**
     * 创建标签 整合 request 请求参数 便于参数校验
     *
     * @param request
     * @return
     */
    private CreateLabelParam requestToCreateLabelParam(CreateLabelRequest request) {
        Label label = request.getLabel();
        List<LabelValue> valuesList = label.getValuesList();

        CreateLabelParam param = new CreateLabelParam();
        List<CreateLabelValueParam> values = new ArrayList<>(valuesList.size());

        // 组织id
        param.setOrgId(request.getOrgId());
        // 标签组id
        param.setLabelGroupId(request.getGid());
        // 联系人类型
        param.setAttribute(request.getMemberTypeValue());

        // 是否自动打标签
        param.setAuto(label.getAuto());
        // 是否手动打标签
        param.setManual(label.getManual());
        // 标签名称
        param.setName(label.getName());

        if (CollectionUtil.isNotEmpty(valuesList)) {
            valuesList.forEach(value -> {
                CreateLabelValueParam createLabelValueParam = new CreateLabelValueParam();
                // 标签值条件
                createLabelValueParam.setCondition(value.getCondition());
                // 标签值序号
                createLabelValueParam.setSerial(value.getSerial());
                // 标签值名称
                createLabelValueParam.setValue(value.getValue());
                values.add(createLabelValueParam);
            });
        }
        param.setValues(values);

        return param;
    }

    /**
     * 获取标签信息 整合 request 请求参数 便于参数校验
     *
     * @param request
     * @return
     */
    private GetLabelInfoParam requestToGetLabelInfoParam(GetLabelInfoRequest request) {
        GetLabelInfoParam param = new GetLabelInfoParam();
        List<String> labelIds = GRpcUtil.protocolStringToListString(request.getIdList());
        // 标签id列表
        param.setIds(labelIds);
        return param;
    }

    /**
     * 检查标签值名称是否重复 整合 request 请求参数 便于参数校验
     *
     * @param request
     * @return
     */
    private CheckLabelValueNameParam requestToCheckTagValueNameParam(CheckLabelValueNameRequest request) {
        CheckLabelValueNameParam param = new CheckLabelValueNameParam();
        // 标签id
        param.setLabelId(request.getLabelId());
        // 标签值名称
        param.setValue(request.getValue());
        return param;
    }

    /**
     * 标签更新 整合 request 请求参数 便于参数校验
     *
     * @param request
     * @return
     */
    private UpdateLabelParam requestToUpdateTagParam(UpdateLabelRequest request) {
        UpdateLabelParam param = new UpdateLabelParam();
        Label label = request.getLabel();
        // 组织id
        param.setOrgId(request.getOrgId());
        // 标签组id
        param.setLabelGroupId(request.getGid());
        // 联系人类型 默认是 0
        param.setAttribute(request.getMemberTypeValue());

        // 是否自动打标签
        param.setAuto(label.getAuto());
        // 是否手动打标签
        param.setManual(label.getManual());
        // 标签名称
        param.setName(label.getName());
        // 标签id
        param.setId(request.getId());

        //计划删除的标签值id列表
        ProtocolStringList deleteValuesList = request.getDeleteValuesList();
        param.setDeleteValues(GRpcUtil.protocolStringToListString(deleteValuesList));

        // 计划添加的标签值
        List<LabelValue> insertValuesList = request.getInsertValuesList();
        if (CollectionUtil.isNotEmpty(insertValuesList)) {
            List<CreateLabelValueParam> params = new ArrayList<>(insertValuesList.size());
            insertValuesList.forEach(tagValue -> {
                CreateLabelValueParam createLabelValueParam = new CreateLabelValueParam();
                // 标签值名称
                createLabelValueParam.setValue(tagValue.getValue());
                // 标签值序号
                createLabelValueParam.setSerial(tagValue.getSerial());
                // 标签值条件
                createLabelValueParam.setCondition(tagValue.getCondition());
                params.add(createLabelValueParam);
            });
            param.setInsertValues(params);

        }

        // 计划更新的标签值
        List<LabelValue> updateValuesList = request.getUpdateValuesList();

        if (CollectionUtil.isNotEmpty(updateValuesList)) {
            List<UpdateLabelValueParam> params = new ArrayList<>(updateValuesList.size());
            updateValuesList.forEach(tagValue -> {
                UpdateLabelValueParam updateLabelValueParam = new UpdateLabelValueParam();
                // 标签值名称
                updateLabelValueParam.setValue(tagValue.getValue());
                // 标签值序号
                updateLabelValueParam.setSerial(tagValue.getSerial());
                // 标签值条件
                updateLabelValueParam.setCondition(tagValue.getCondition());
                // 标签值id
                updateLabelValueParam.setId(tagValue.getId());
                params.add(updateLabelValueParam);
            });
            param.setUpdateValues(params);
        }

        return param;
    }

    /**
     * 标签删除 整合 request 请求参数 便于参数校验
     *
     * @param request
     * @return
     */
    private DeleteLabelParam requestToDeleteLabelParam(DeleteLabelRequest request) {
        DeleteLabelParam param = new DeleteLabelParam();
        // 标签id
        param.setId(request.getId());
        // 组织id
        param.setOrgId(request.getOrgId());
        return param;
    }

    /**
     * List<TagDTO> 转 List<Tag>
     *
     * @param labelDTOList
     * @param includeValue 是否包含 value
     * @return
     */
    private List<Label> labelDtoListToInfo(List<LabelDTO> labelDTOList, Boolean includeValue) {
        List<Label> labels = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(labelDTOList)) {
            labelDTOList.forEach(labelDTO -> {
                // 标签 赋值 默认值
                GRpcUtil.fillDefaultValue(labelDTO);
                Label.Builder labelBuilder = Label.newBuilder();
                // 标签名称
                labelBuilder.setName(labelDTO.getName());
                // 标签id
                labelBuilder.setId(labelDTO.getId());
                // 标签组id
                labelBuilder.setGid(labelDTO.getTagGroupId());
                // 组织id
                labelBuilder.setOrgId(labelDTO.getOrgId());
                // 是否手动打标签
                labelBuilder.setManual(labelDTO.getManual());
                // 是否自动打标签
                labelBuilder.setAuto(labelDTO.getAuto());
                // 基础信息
                labelBuilder.setBase(buildBaseMessage(labelDTO.getCreateTime(), labelDTO.getUpdateTime()));

                if (includeValue) {
                    List<LabelValueDTO> valueDTOS = labelDTO.getValues();
                    if (CollectionUtil.isNotEmpty(valueDTOS)) {
                        List<LabelValue> values = new ArrayList<>(valueDTOS.size());
                        valueDTOS.forEach(v -> {
                            // 赋默认值
                            GRpcUtil.fillDefaultValue(v);
                            LabelValue.Builder builder = LabelValue.newBuilder();
                            // 标签值id
                            builder.setId(v.getId());
                            // 组织id
                            builder.setOrgId(v.getOrgId());
                            // 标签组id
                            builder.setGid(v.getLabelGroupId());
                            // 标签组名称
                            builder.setLabelGroupName(v.getLabelGroupName());
                            // 标签id
                            builder.setLabelId(v.getLabelId());
                            // 标签名称
                            builder.setLabelName(v.getLabelName());
                            // 标签值名称
                            builder.setValue(v.getValue());
                            // 标签值序号
                            builder.setSerial(v.getSerial());
                            // 标签值条件
                            builder.setCondition(v.getCondition());
                            // 是否手动打标签
                            builder.setManual(v.getManual());
                            // 是否自动打标签
                            builder.setAuto(v.getAuto());
                            // 基础信息
                            builder.setBase(buildBaseMessage(v.getCreateTime(), v.getUpdateTime()));
                            values.add(builder.build());

                        });
                        labelBuilder.addAllValues(values);
                    }
                }
                labels.add(labelBuilder.build());
            });
        }
        return labels;
    }

    /**
     * 构建 BaseMessage
     *
     * @param createTime
     * @param updateTime
     * @return
     */
    private BaseMessage buildBaseMessage(Date createTime, Date updateTime) {
        BaseMessage.Builder baseMessageBuilder = BaseMessage.newBuilder();
        // 创建时间
        baseMessageBuilder.setCreateTime(GRpcUtil.getTimestamp(createTime));
        // 修改时间
        baseMessageBuilder.setUpdateTime(GRpcUtil.getTimestamp(updateTime));
        return baseMessageBuilder.build();
    }

    /**
     * 请求参数 转 BatchUpdateTagValuesParam
     *
     * @param request
     * @return
     */
    private BatchUpdateLabelValuesParm requestToBatchUpdateLabelValuesParam(BatchUpdateLabelValuesRequest request) {
        BatchUpdateLabelValuesParm parm = new BatchUpdateLabelValuesParm();
        List<LabelValue> tagValuesList = request.getLabelValuesList();
        List<BatchUpdateLabelValueParm> batchUpdateLabelValueParmList = new ArrayList<>();
        for (int i = 0; i < tagValuesList.size(); i++) {
            LabelValue value = tagValuesList.get(i);
            BatchUpdateLabelValueParm batchUpdateLabelValueParm = new BatchUpdateLabelValueParm();
            // 标签值id
            batchUpdateLabelValueParm.setId(value.getId());
            // 标签值序号
            batchUpdateLabelValueParm.setSerial(value.getSerial());
            batchUpdateLabelValueParmList.add(batchUpdateLabelValueParm);
        }
        parm.setValues(batchUpdateLabelValueParmList);
        return parm;
    }

    private LabelInfo labelInfoDtoToLabelInfo(LabelInfoDTO labelInfoDTO) {
        LabelInfo.Builder labelInfoBuilder = LabelInfo.newBuilder();

        // 添加默认值 - 标签组
        GRpcUtil.fillDefaultValue(labelInfoDTO);

        List<LabelDTO> labelDTOS = labelInfoDTO.getLabels();
        List<Label> tags = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(labelDTOS)) {
            labelDTOS.forEach(label -> {
                // 添加默认值 - 标签
                GRpcUtil.fillDefaultValue(label);
                Label.Builder labelBuilder = Label.newBuilder();
                List<LabelValueDTO> values = label.getValues();
                List<LabelValue> tagValues = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(values)) {
                    values.forEach(v -> {
                        // 添加默认值 - 标签值
                        GRpcUtil.fillDefaultValue(v);

                        LabelValue.Builder labelValueBuilder = LabelValue.newBuilder();
                        // 标签值序号
                        labelValueBuilder.setSerial(v.getSerial());
                        // 标签值id
                        labelValueBuilder.setId(v.getId());
                        // 标签id
                        labelValueBuilder.setLabelId(v.getLabelId());
                        // 标签名称
                        labelValueBuilder.setLabelName(v.getLabelName());
                        // 标签组id
                        labelValueBuilder.setGid(v.getLabelGroupId());
                        // 标签组名称
                        labelValueBuilder.setLabelGroupName(v.getLabelGroupName());
                        // 组织id
                        labelValueBuilder.setOrgId(v.getOrgId());
                        // 标签值名称
                        labelValueBuilder.setValue(v.getValue());
                        //标签值条件
                        labelValueBuilder.setCondition(v.getCondition());
                        // 是否手动打标签
                        labelValueBuilder.setManual(v.getManual());
                        // 是否自动打标签
                        labelValueBuilder.setAuto(v.getAuto());
                        // 联系人类型
                        labelValueBuilder.setAttribute(v.getAttribute());
                        tagValues.add(labelValueBuilder.build());
                    });
                }
                // 是否自动打标签
                labelBuilder.setAuto(label.getAuto());
                // 标签id
                labelBuilder.setId(label.getId());
                // 是否手动打标签
                labelBuilder.setManual(label.getManual());
                // 标签名称
                labelBuilder.setName(label.getName());
                // 组织id
                labelBuilder.setOrgId(label.getOrgId());
                // 标签组id
                labelBuilder.setGid(label.getTagGroupId());
                // 标签值
                labelBuilder.addAllValues(tagValues);
                tags.add(labelBuilder.build());
            });

        }
        // 标签组id
        labelInfoBuilder.setId(labelInfoDTO.getId());
        // 标签组名称
        labelInfoBuilder.setName(labelInfoDTO.getName());
        // 联系人类型
        labelInfoBuilder.setMemberTypeValue(labelInfoDTO.getAttribute());
        // 组织id
        labelInfoBuilder.setOrgId(labelInfoDTO.getOrgId());
        // 标签组序号
        labelInfoBuilder.setSerial(labelInfoDTO.getSerial());
        labelInfoBuilder.addAllLabels(tags);
        return labelInfoBuilder.build();
    }

    private ListLabelsParam requestToListLabelsParam(ListLabelsRequest request) {
        ListLabelsParam param = new ListLabelsParam();
        // 组织id
        param.setOrgId(request.getOrgId());
        // 联系人类型 默认是0 个人联系人
        param.setAttribute(request.getMemberTypeValue());
        // 是否返回标签值信息 默认是false
        param.setIncludeValue(request.getIncludeValue());
        return param;
    }

    /**
     * LabelValueDTO 转 LabelValue
     *
     * @param labelValueDTO
     * @return
     */
    private LabelValue labelValueDtoToLabelValue(LabelValueDTO labelValueDTO) {
        LabelValue.Builder builder = LabelValue.newBuilder();
        // 设置默认值
        GRpcUtil.fillDefaultValue(labelValueDTO);

        // 标签值id
        builder.setId(labelValueDTO.getId());
        // 标签值序号
        builder.setSerial(labelValueDTO.getSerial());
        // 标签值条件
        builder.setCondition(labelValueDTO.getCondition());
        // 标签值名称
        builder.setValue(labelValueDTO.getValue());
        // 组织id
        builder.setOrgId(labelValueDTO.getOrgId());
        // 联系人类型
        builder.setAttribute(labelValueDTO.getAttribute());
        // 标签组id
        builder.setGid(labelValueDTO.getLabelGroupId());
        // 标签组名称
        builder.setLabelGroupName(labelValueDTO.getLabelGroupName());
        // 标签id
        builder.setLabelId(labelValueDTO.getLabelId());
        // 标签名称
        builder.setLabelName(labelValueDTO.getLabelName());
        // 是否手动打标签
        builder.setManual(labelValueDTO.getManual());
        // 是否自动打标签
        builder.setAuto(labelValueDTO.getAuto());
        return builder.build();
    }

    /**
     * 构建 获取标签值列表请求参数
     *
     * @param request
     * @return
     */
    private ListLabelValuesParam requestToListLabelValuesParam(ListLabelValuesRequest request) {
        ListLabelValuesParam param = new ListLabelValuesParam();
        // 联系人类型 默认是0
        param.setAttribute(request.getMemberTypeValue());
        // 组织id
        param.setOrgId(request.getOrgId());

        ProtocolStringList idsList = request.getIdsList();
        // 标签值id列表
        List<String> ids = GRpcUtil.protocolStringToListString(idsList);
        param.setIds(ids);
        return param;
    }

}
